1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module glib.Timeout; 26 27 private import core.time; 28 private import glib.Source; 29 private import glib.c.functions; 30 public import glib.c.types; 31 private import std.conv; 32 33 34 /** */ 35 public class Timeout 36 { 37 /** Holds all idle delegates */ 38 private bool delegate()[] timeoutListeners; 39 /** Our timeout ID */ 40 private uint timeoutID; 41 42 43 /** 44 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. 45 * 46 * Note that timeout functions may be delayed, due to the processing of other 47 * event sources. Thus they should not be relied on for precise timing. 48 * After each call to the timeout function, the time of the next timeout is 49 * recalculated based on the current time and the given interval 50 * (it does not try to 'catch up' time lost in delays). 51 * Params: 52 * interval = the timeout in milieconds 53 * delegate() = the delegate to be executed 54 * fireNow = When true the delegate will be executed emmidiatly 55 */ 56 this(uint interval, bool delegate() dlg, bool fireNow=false) 57 { 58 if ( fireNow && !dlg() ) 59 return; 60 61 timeoutListeners ~= dlg; 62 timeoutID = g_timeout_add_full(GPriority.DEFAULT, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 63 } 64 65 this(Duration interval, bool delegate() dlg, bool fireNow=false) 66 { 67 this(interval.total!"msecs".to!uint, dlg, fireNow); 68 } 69 70 /** 71 * Creates a new timeout cycle. 72 * Params: 73 * interval = the timeout in milieconds 74 * delegate() = the delegate to be executed 75 * priority = Priority for the timeout function 76 * fireNow = When true the delegate will be executed emmidiatly 77 */ 78 this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false) 79 { 80 if ( fireNow && !dlg() ) 81 return; 82 83 timeoutListeners ~= dlg; 84 timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 85 } 86 87 this(Duration interval, bool delegate() dlg, GPriority priority, bool fireNow=false) 88 { 89 this(interval.total!"msecs".to!uint, dlg, priority, fireNow); 90 } 91 92 /** 93 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. 94 * Params: 95 * delegate() = the delegate to be executed 96 * seconds = interval in seconds. 97 * fireNow = When true the delegate will be executed emmidiatly 98 */ 99 this(bool delegate() dlg, uint seconds, bool fireNow=false) 100 { 101 if ( fireNow && !dlg() ) 102 return; 103 104 timeoutListeners ~= dlg; 105 timeoutID = g_timeout_add_seconds_full(GPriority.DEFAULT, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 106 } 107 108 this(bool delegate() dlg, Duration seconds, bool fireNow=false) 109 { 110 this(dlg, seconds.total!"seconds".to!uint, fireNow); 111 } 112 113 /** 114 * Creates a new timeout cycle. 115 * Params: 116 * delegate() = the delegate to be executed 117 * seconds = interval in seconds. 118 * priority = Priority for the timeout function 119 * fireNow = When true the delegate will be executed emmidiatly 120 */ 121 this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false) 122 { 123 if ( fireNow && !dlg() ) 124 return; 125 126 timeoutListeners ~= dlg; 127 timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 128 } 129 130 this(bool delegate() dlg, Duration seconds, GPriority priority, bool fireNow=false) 131 { 132 this(dlg, seconds.total!"seconds".to!uint, priority, fireNow); 133 } 134 135 /** Removes the timeout from gtk */ 136 public void stop() 137 { 138 if ( timeoutID > 0 ) 139 { 140 g_source_remove(timeoutID); 141 } 142 } 143 144 /** 145 * Removes the timeout from gtk 146 */ 147 ~this() 148 { 149 stop(); 150 } 151 152 /** 153 * Adds a new delegate to this timeout cycle 154 * Params: 155 * dlg = 156 * fireNow = 157 */ 158 public void addListener(bool delegate() dlg, bool fireNow=false) 159 { 160 if ( fireNow && !dlg() ) 161 return; 162 163 timeoutListeners ~= dlg; 164 } 165 166 /** 167 * The callback execution from glib 168 * Params: 169 * timeout = 170 * Returns: 171 */ 172 extern(C) static bool timeoutCallback(Timeout timeout) 173 { 174 bool runAgain = false; 175 int i = 0; 176 177 while ( i<timeout.timeoutListeners.length ) 178 { 179 if ( !timeout.timeoutListeners[i]() ) 180 { 181 timeout.timeoutListeners = timeout.timeoutListeners[0..i] ~ timeout.timeoutListeners[i+1..$]; 182 } 183 else 184 { 185 runAgain = true; 186 ++i; 187 } 188 } 189 190 return runAgain; 191 } 192 193 /* 194 * Reset the timeout object when it's destroyed on the GTK side. 195 */ 196 extern(C) static void destroyTimeoutNotify(Timeout timeout) 197 { 198 timeout.timeoutListeners.length = 0; 199 timeout.timeoutID = 0; 200 } 201 202 /** 203 */ 204 205 /** 206 * Sets a function to be called at regular intervals, with the default 207 * priority, %G_PRIORITY_DEFAULT. 208 * 209 * The given @function is called repeatedly until it returns %G_SOURCE_REMOVE 210 * or %FALSE, at which point the timeout is automatically destroyed and the 211 * function will not be called again. The first call to the function will be 212 * at the end of the first @interval. 213 * 214 * Note that timeout functions may be delayed, due to the processing of other 215 * event sources. Thus they should not be relied on for precise timing. 216 * After each call to the timeout function, the time of the next 217 * timeout is recalculated based on the current time and the given interval 218 * (it does not try to 'catch up' time lost in delays). 219 * 220 * See [memory management of sources][mainloop-memory-management] for details 221 * on how to handle the return value and memory management of @data. 222 * 223 * If you want to have a timer in the "seconds" range and do not care 224 * about the exact time of the first call of the timer, use the 225 * g_timeout_add_seconds() function; this function allows for more 226 * optimizations and more efficient system power usage. 227 * 228 * This internally creates a main loop source using g_timeout_source_new() 229 * and attaches it to the global #GMainContext using g_source_attach(), so 230 * the callback will be invoked in whichever thread is running that main 231 * context. You can do these steps manually if you need greater control or to 232 * use a custom main context. 233 * 234 * It is safe to call this function from any thread. 235 * 236 * The interval given is in terms of monotonic time, not wall clock 237 * time. See g_get_monotonic_time(). 238 * 239 * Params: 240 * interval = the time between calls to the function, in milliseconds 241 * (1/1000ths of a second) 242 * function_ = function to call 243 * data = data to pass to @function 244 * 245 * Returns: the ID (greater than 0) of the event source. 246 */ 247 public static uint add(uint interval, GSourceFunc function_, void* data) 248 { 249 return g_timeout_add(interval, function_, data); 250 } 251 252 /** 253 * Sets a function to be called at regular intervals, with the given 254 * priority. The function is called repeatedly until it returns 255 * %FALSE, at which point the timeout is automatically destroyed and 256 * the function will not be called again. The @notify function is 257 * called when the timeout is destroyed. The first call to the 258 * function will be at the end of the first @interval. 259 * 260 * Note that timeout functions may be delayed, due to the processing of other 261 * event sources. Thus they should not be relied on for precise timing. 262 * After each call to the timeout function, the time of the next 263 * timeout is recalculated based on the current time and the given interval 264 * (it does not try to 'catch up' time lost in delays). 265 * 266 * See [memory management of sources][mainloop-memory-management] for details 267 * on how to handle the return value and memory management of @data. 268 * 269 * This internally creates a main loop source using g_timeout_source_new() 270 * and attaches it to the global #GMainContext using g_source_attach(), so 271 * the callback will be invoked in whichever thread is running that main 272 * context. You can do these steps manually if you need greater control or to 273 * use a custom main context. 274 * 275 * The interval given is in terms of monotonic time, not wall clock time. 276 * See g_get_monotonic_time(). 277 * 278 * Params: 279 * priority = the priority of the timeout source. Typically this will be in 280 * the range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH. 281 * interval = the time between calls to the function, in milliseconds 282 * (1/1000ths of a second) 283 * function_ = function to call 284 * data = data to pass to @function 285 * notify = function to call when the timeout is removed, or %NULL 286 * 287 * Returns: the ID (greater than 0) of the event source. 288 */ 289 public static uint addFull(int priority, uint interval, GSourceFunc function_, void* data, GDestroyNotify notify) 290 { 291 return g_timeout_add_full(priority, interval, function_, data, notify); 292 } 293 294 /** 295 * Sets a function to be called at regular intervals with the default 296 * priority, %G_PRIORITY_DEFAULT. 297 * 298 * The function is called repeatedly until it returns %G_SOURCE_REMOVE 299 * or %FALSE, at which point the timeout is automatically destroyed 300 * and the function will not be called again. 301 * 302 * This internally creates a main loop source using 303 * g_timeout_source_new_seconds() and attaches it to the main loop context 304 * using g_source_attach(). You can do these steps manually if you need 305 * greater control. Also see g_timeout_add_seconds_full(). 306 * 307 * It is safe to call this function from any thread. 308 * 309 * Note that the first call of the timer may not be precise for timeouts 310 * of one second. If you need finer precision and have such a timeout, 311 * you may want to use g_timeout_add() instead. 312 * 313 * See [memory management of sources][mainloop-memory-management] for details 314 * on how to handle the return value and memory management of @data. 315 * 316 * The interval given is in terms of monotonic time, not wall clock 317 * time. See g_get_monotonic_time(). 318 * 319 * Params: 320 * interval = the time between calls to the function, in seconds 321 * function_ = function to call 322 * data = data to pass to @function 323 * 324 * Returns: the ID (greater than 0) of the event source. 325 * 326 * Since: 2.14 327 */ 328 public static uint addSeconds(uint interval, GSourceFunc function_, void* data) 329 { 330 return g_timeout_add_seconds(interval, function_, data); 331 } 332 333 /** 334 * Sets a function to be called at regular intervals, with @priority. 335 * 336 * The function is called repeatedly until it returns %G_SOURCE_REMOVE 337 * or %FALSE, at which point the timeout is automatically destroyed and 338 * the function will not be called again. 339 * 340 * Unlike g_timeout_add(), this function operates at whole second granularity. 341 * The initial starting point of the timer is determined by the implementation 342 * and the implementation is expected to group multiple timers together so that 343 * they fire all at the same time. To allow this grouping, the @interval to the 344 * first timer is rounded and can deviate up to one second from the specified 345 * interval. Subsequent timer iterations will generally run at the specified 346 * interval. 347 * 348 * Note that timeout functions may be delayed, due to the processing of other 349 * event sources. Thus they should not be relied on for precise timing. 350 * After each call to the timeout function, the time of the next 351 * timeout is recalculated based on the current time and the given @interval 352 * 353 * See [memory management of sources][mainloop-memory-management] for details 354 * on how to handle the return value and memory management of @data. 355 * 356 * If you want timing more precise than whole seconds, use g_timeout_add() 357 * instead. 358 * 359 * The grouping of timers to fire at the same time results in a more power 360 * and CPU efficient behavior so if your timer is in multiples of seconds 361 * and you don't require the first timer exactly one second from now, the 362 * use of g_timeout_add_seconds() is preferred over g_timeout_add(). 363 * 364 * This internally creates a main loop source using 365 * g_timeout_source_new_seconds() and attaches it to the main loop context 366 * using g_source_attach(). You can do these steps manually if you need 367 * greater control. 368 * 369 * It is safe to call this function from any thread. 370 * 371 * The interval given is in terms of monotonic time, not wall clock 372 * time. See g_get_monotonic_time(). 373 * 374 * Params: 375 * priority = the priority of the timeout source. Typically this will be in 376 * the range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH. 377 * interval = the time between calls to the function, in seconds 378 * function_ = function to call 379 * data = data to pass to @function 380 * notify = function to call when the timeout is removed, or %NULL 381 * 382 * Returns: the ID (greater than 0) of the event source. 383 * 384 * Since: 2.14 385 */ 386 public static uint addSecondsFull(int priority, uint interval, GSourceFunc function_, void* data, GDestroyNotify notify) 387 { 388 return g_timeout_add_seconds_full(priority, interval, function_, data, notify); 389 } 390 391 /** 392 * Creates a new timeout source. 393 * 394 * The source will not initially be associated with any #GMainContext 395 * and must be added to one with g_source_attach() before it will be 396 * executed. 397 * 398 * The interval given is in terms of monotonic time, not wall clock 399 * time. See g_get_monotonic_time(). 400 * 401 * Params: 402 * interval = the timeout interval in milliseconds. 403 * 404 * Returns: the newly-created timeout source 405 */ 406 public static Source sourceNew(uint interval) 407 { 408 auto __p = g_timeout_source_new(interval); 409 410 if(__p is null) 411 { 412 return null; 413 } 414 415 return new Source(cast(GSource*) __p, true); 416 } 417 418 /** 419 * Creates a new timeout source. 420 * 421 * The source will not initially be associated with any #GMainContext 422 * and must be added to one with g_source_attach() before it will be 423 * executed. 424 * 425 * The scheduling granularity/accuracy of this timeout source will be 426 * in seconds. 427 * 428 * The interval given is in terms of monotonic time, not wall clock time. 429 * See g_get_monotonic_time(). 430 * 431 * Params: 432 * interval = the timeout interval in seconds 433 * 434 * Returns: the newly-created timeout source 435 * 436 * Since: 2.14 437 */ 438 public static Source sourceNewSeconds(uint interval) 439 { 440 auto __p = g_timeout_source_new_seconds(interval); 441 442 if(__p is null) 443 { 444 return null; 445 } 446 447 return new Source(cast(GSource*) __p, true); 448 } 449 }